package main

import (
	"../deps/lessgo/pass"
	"./conf"
	"./store"
	"flag"
	"fmt"
	"os"
	"os/user"
	"regexp"
	"strings"
)

const (
	CMDC_RED    = "\033[31m"
	CMDC_GREEN  = "\033[32m"
	CMDC_CLOSE  = "\033[0m"
	helpMessage = `lesskeeper-cli 

Usage: lesskeeper-cli [flags]
  --userset: Create a System Administrator Password
  --help: Display this help and exit
`
)

var (
	err          error
	flagPrefix   = flag.String("prefix", "", "the prefix folder path")
	flagUserSet  = flag.Bool("userset", false, "Create a System Administrator Password")
	flagUserName = flag.String("username", "keeperadmin", "the user name")
	flagPassword = flag.String("password", "changethis", "the password")
	flagHelp     = flag.Bool("help", false, "Display help and exit")
	unamePattern = regexp.MustCompile("^[a-z]{1}[a-z0-9]{3,20}$")
)

func main() {

	//
	if u, err := user.Current(); err != nil || u.Uid != "0" {
		fmt.Println("Permission Denied : must be run as root")
		//os.Exit(1)
	}

	//
	flag.Parse()
	if err := conf.Initialize(*flagPrefix); err != nil {
		fmt.Println("conf.Initialize error: %v", err)
		os.Exit(1)
	}

	if err := store.Initialize(); err != nil {
		fmt.Println("store.Initialize error: %v", err)
		os.Exit(1)
	}

	if *flagUserSet {
		cmdUserSet()
	} else if *flagHelp {
		fmt.Println(helpMessage)
	} else {
		fmt.Println(CMDC_RED + "No Command Found" + CMDC_CLOSE)
		fmt.Println(helpMessage)
		os.Exit(1)
	}
}

func cmdUserSet() {

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Panic:", r)
		}
	}()

	//
	keeperid := store.Cmd("HGET", "sys:keeper", "id").String()
	if len(keeperid) > 0 {
		fmt.Printf("%sSetup is complete!\nplease login use http://ip-address:%s/ to management in your browser%s\n",
			CMDC_RED,
			conf.Config.KeeperPort,
			CMDC_CLOSE)
		os.Exit(1)
	}

	uname := strings.ToLower(strings.TrimSpace(*flagUserName))
	if len(uname) < 4 || len(uname) > 20 {
		fmt.Println(CMDC_RED + "Username must be between 4 and 20 characters long" + CMDC_CLOSE)
		os.Exit(1)
	}

	if matched := unamePattern.MatchString(uname); !matched {
		fmt.Println(CMDC_RED + "Username must consist of letters or numbers, and begin with a letter" + CMDC_CLOSE)
		os.Exit(1)
	}

	if len(*flagPassword) < 8 || len(*flagPassword) > 30 {
		fmt.Println(CMDC_RED + "Password must be between 8 and 30 characters long" + CMDC_CLOSE)
		os.Exit(1)
	}

	ver, _ := store.Cmd("INCRBY", "sys:keeper:ver", 1).Uint64()
	passwd, _ := pass.HashDefault(*flagPassword)
	node := store.NodeProposal{
		Key:    "/sys/ids/" + uname,
		Val:    passwd,
		VerSet: ver,
	}
	store.NodeSet(&node)

	//
	fmt.Println(CMDC_GREEN + "Successfully created" + CMDC_CLOSE)
	os.Exit(0)
}
